package com.example.scheduler.config;

import com.example.scheduler.entity.TaskConfig;
import com.example.scheduler.executor.TaskExecutor;
import com.example.scheduler.repository.TaskConfigRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.PeriodicTrigger;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

import java.util.Collection;

@Slf4j
@Configuration
@EnableScheduling
public class DynamicSchedulerConfig implements SchedulingConfigurer {

    @Autowired
    private TaskConfigRepository taskConfigRepository;

    @Autowired
    private Collection<TaskExecutor> taskExecutors;

    private ScheduledTaskRegistrar taskRegistrar;
    private final Map<String, ScheduledFuture<?>> scheduledTasks = new HashMap<>();
    private final Map<String, TaskExecutor> taskExecutorMap = new HashMap<>();

    @Autowired
    public void initTaskExecutors() {
        taskExecutors.forEach(executor -> taskExecutorMap.put(executor.getTaskName(), executor));
    }

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        scheduler.setThreadNamePrefix("task-scheduler-");
        scheduler.initialize();
        return scheduler;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setTaskScheduler(taskScheduler());
        this.taskRegistrar = taskRegistrar;
        
        // 初始化时加载所有启用的任务
        List<TaskConfig> enabledTasks = taskConfigRepository.findByEnabled("1");
        enabledTasks.forEach(this::scheduleTask);
    }



    private void scheduleTask(TaskConfig taskConfig) {
        Runnable runnable = () -> {
            // 每次执行任务时重新获取最新的任务配置
            TaskConfig latestConfig = taskConfigRepository.findById(taskConfig.getId())
                    .orElseThrow(() -> new RuntimeException("任务配置不存在: " + taskConfig.getTaskName()));
            
            // 检查任务是否已被禁用
            if (!latestConfig.isEnabled()) {
                log.info("任务已被禁用，跳过执行: {}", latestConfig.getTaskName());
                return;
            }

            try {
                log.info("执行任务: {}", latestConfig.getTaskName());
                // 执行具体的任务逻辑
                executeTask(latestConfig);
                
                latestConfig.setLastErrorCode(200);
                latestConfig.setLastErrorMsg("成功");
            } catch (Exception e) {
                log.error("任务执行失败: {}", latestConfig.getTaskName(), e);
                latestConfig.setLastErrorCode(500);
                latestConfig.setLastErrorMsg(e.getMessage());
            }
            latestConfig.setUpdateTime(LocalDateTime.now());
            taskConfigRepository.save(latestConfig);
        };

        ScheduledFuture<?> future;
        if (taskConfig.getFixedDelay() != null) {
            future = taskRegistrar.getScheduler().schedule(
                runnable,
                new PeriodicTrigger(taskConfig.getFixedDelay())
            );
        } else {
            future = taskRegistrar.getScheduler().schedule(
                runnable,
                new CronTrigger(taskConfig.getCronExpression())
            );
        }

        scheduledTasks.put(taskConfig.getTaskName(), future);
    }

    private void executeTask(TaskConfig taskConfig) {
        TaskExecutor executor = taskExecutorMap.get(taskConfig.getTaskName());
        if (executor != null) {
            executor.execute(taskConfig);
        } else {
            log.warn("未知的任务类型: {}", taskConfig.getTaskName());
        }
    }
}